#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI日报生成器
基于Git提交信息，通过LangChain和Ollama生成智能化的工作日报
"""

import argparse
import os
import sys
from datetime import datetime
from pathlib import Path
from typing import List, Dict

# 导入LangChain相关模块
try:
    from langchain_community.llms import Ollama
    from langchain_community.llms import Tongyi
    from langchain.prompts import PromptTemplate
    from langchain.schema import BaseOutputParser
    from langchain.chains import LLMChain
except ImportError:
    print("请安装LangChain: pip install langchain langchain-community dashscope")
    sys.exit(1)

# 导入我们的日报生成器
from daily_report_generator import DailyReportGenerator, CommitInfo

# 设置日志
from loguru import logger


class DailyReportOutputParser(BaseOutputParser):
    """日报输出解析器"""

    def parse(self, text: str) -> str:
        """解析AI生成的日报内容"""
        return text.strip()


class AIDailyReportGenerator:
    """AI日报生成器"""

    def __init__(self, llm_provider: str, llm_config: Dict[str, str], source_dir: str, user_id: str):
        self.source_dir = source_dir
        self.user_id = user_id

        # 根据提供商初始化LLM
        if llm_provider.lower() == 'dashscope':
            # 设置DashScope API Key
            os.environ['DASHSCOPE_API_KEY'] = llm_config.get('api_key', '')
            self.llm = Tongyi(
                model_name=llm_config.get('model', 'qwen-plus'),
                temperature=0.7
            )
        elif llm_provider.lower() == 'ollama':
            self.llm = Ollama(
                base_url=llm_config.get('base_url', 'http://localhost:11434'),
                model=llm_config.get('model', 'llama2'),
                temperature=0.7
            )
        else:
            raise ValueError(f"不支持的LLM提供商: {llm_provider}")

        # 初始化基础日报生成器
        self.base_generator = DailyReportGenerator(source_dir, user_id)

        # 创建日报生成提示模板（专业研发版本）
        self.daily_prompt_template = PromptTemplate(
            input_variables=["date", "commits_summary", "user_name"],
            template="""你是一个专业的研发工作总结助手，专门服务于水利水文、地学、大模型、物联网等技术领域的研发工作。请根据以下Git提交记录，生成一份专业的研发工作日报。

日期: {date}
研发人员: {user_name}

Git提交详情:
{commits_summary}

请生成一份研发工作日报，要求：
1. 真实反映当日的研发工作内容，基于实际代码提交推断研发活动
2. 按项目分类总结研发工作，识别项目所属专业领域（水文水利、地学研究、AI模型开发、物联网系统等）
3. 突出技术创新、算法改进、模型优化、系统架构等研发成果
4. 使用专业术语，体现研发工作的技术深度和创新性
5. 重点关注功能开发、算法实现、数据处理、模型训练、系统集成等研发活动
6. 字数控制在200-400字范围内，内容充实但简洁

日报格式要求：
## {date} 研发工作总结

**工作统计：** X次提交，X个项目，代码变更 +X/-X 行

**主要研发内容：**
1. 项目A（领域标识）：具体的研发工作描述，包括技术方案、算法改进等
2. 项目B（领域标识）：具体的研发工作描述，包括功能开发、性能优化等
3. 项目C（领域标识）：具体的研发工作描述，包括系统集成、数据处理等

**技术创新点：**
- 算法优化：具体的算法改进或创新
- 架构升级：系统架构的改进或重构
- 性能提升：性能优化的具体成果
- 功能扩展：新功能的技术实现

**研发进展：**
简要总结当日研发工作的整体进展和技术收获

请严格按照上述格式生成专业的研发工作日报："""
        )

        # 创建月度总结提示模板（专业研发版本）
        self.monthly_prompt_template = PromptTemplate(
            input_variables=["year", "month", "monthly_summary", "user_name"],
            template="""你是一个专业的研发工作总结助手，专门服务于水利水文、地学、大模型、物联网等技术领域的研发工作。请根据以下月度Git提交统计信息，生成一份专业的研发工作月度总结。

时间: {year}年{month}月
研发人员: {user_name}

月度工作统计:
{monthly_summary}

请生成一份研发工作月度总结，要求：
1. 真实反映整月的研发工作内容和技术成果
2. 按项目和专业领域分类总结主要研发工作
3. 突出技术创新、算法优化、系统架构改进、模型性能提升等研发成果
4. 使用专业术语，体现研发工作的技术深度和学术价值
5. 重点关注功能开发、算法实现、数据处理、模型训练、系统集成、性能优化等
6. 字数控制在400-600字范围内，内容详实且专业

月度总结格式要求：
# {year}年{month}月研发工作总结

## 工作量统计
- 总提交次数：X次
- 涉及项目：X个（水文水利X个，地学研究X个，AI模型X个，物联网X个）
- 代码变更：新增X行，删除X行
- 活跃天数：X天

## 主要研发项目
### 水文水利领域
- 项目名称：完成的主要研发工作和技术创新
- 关键技术：算法改进、模型优化、数据处理等

### 地学研究领域  
- 项目名称：完成的主要研发工作和技术创新
- 关键技术：数据分析、模型构建、系统开发等

### AI模型开发
- 项目名称：完成的主要研发工作和技术创新
- 关键技术：模型训练、算法优化、性能提升等

### 物联网系统
- 项目名称：完成的主要研发工作和技术创新
- 关键技术：系统集成、数据采集、通信协议等

## 技术创新亮点
- 算法创新：具体的算法改进和创新成果
- 架构优化：系统架构的重大改进和升级
- 性能突破：关键性能指标的显著提升
- 功能扩展：重要新功能的技术实现

## 研发成果总结
简要总结本月研发工作的整体情况、技术收获和创新价值

请严格按照上述格式生成专业的研发工作月度总结："""
        )

        # 创建LLM链
        self.daily_chain = LLMChain(
            llm=self.llm,
            prompt=self.daily_prompt_template,
            output_parser=DailyReportOutputParser()
        )

        self.monthly_chain = LLMChain(
            llm=self.llm,
            prompt=self.monthly_prompt_template,
            output_parser=DailyReportOutputParser()
        )

    def format_commits_for_ai(self, commits: List[CommitInfo]) -> str:
        """格式化提交信息供AI处理"""
        if not commits:
            return "当日无提交记录"

        # 按仓库分组
        from collections import defaultdict
        repo_commits = defaultdict(list)
        for commit in commits:
            repo_commits[commit.repo_name].append(commit)

        formatted_lines = []

        for repo_name, repo_commits_list in repo_commits.items():
            formatted_lines.append(f"项目: {repo_name}")

            for commit in repo_commits_list:
                time_str = commit.date.strftime("%H:%M")
                message = commit.message.split('\n')[0]  # 只取第一行

                formatted_lines.append(f"  {time_str} - {message}")
                formatted_lines.append(
                    f"    文件变更: {len(commit.files_changed)}个文件, +{commit.insertions}行 -{commit.deletions}行")

            formatted_lines.append("")

        return "\n".join(formatted_lines)

    def generate_daily_ai_report(self, year: int, month: int, day: int) -> str:
        """生成指定日期的AI日报"""
        logger.info(f"生成 {year}-{month:02d}-{day:02d} 的AI日报")

        # 获取当日提交信息
        daily_commits = self.base_generator.collect_monthly_commits(year, month)
        day_commits = daily_commits.get(day, [])

        if not day_commits:
            return f"## {year}-{month:02d}-{day:02d} 工作日报\n\n当日无提交记录，可能是休息日或未进行代码开发工作。"

        # 格式化提交信息
        commits_summary = self.format_commits_for_ai(day_commits)
        date_str = f"{year}-{month:02d}-{day:02d}"

        try:
            # 使用AI生成日报
            ai_report = self.daily_chain.run(
                date=date_str,
                commits_summary=commits_summary,
                user_name=self.user_id
            )

            return ai_report

        except Exception as e:
            logger.error(f"AI生成日报失败: {e}")
            # 降级到基础格式
            return self._generate_fallback_daily_report(year, month, day, day_commits)

    def generate_monthly_ai_summary(self, year: int, month: int) -> str:
        """生成月度AI总结 - 已废弃，改为每日单独文件模式"""
        logger.info(f"月度总结功能已移除，改为每日单独文件模式")
        
        # 不再生成月度总结，返回说明信息
        return f"# {year}年{month}月工作报告\n\n月度总结功能已移除，请使用每日单独文件模式查看工作记录。\n"

    def generate_full_monthly_ai_reports(self, year: int, month: int) -> Dict[str, str]:
        """生成完整的月度AI日报（每日+月度总结）"""
        logger.info(f"生成 {year}年{month}月 的完整AI日报")

        # 获取所有提交信息
        daily_commits = self.base_generator.collect_monthly_commits(year, month)

        reports = {}

        # 生成每日AI日报
        for day in sorted(daily_commits.keys()):
            daily_report = self.generate_daily_ai_report(year, month, day)
            reports[f"{year}-{month:02d}-{day:02d}"] = daily_report

        # 生成月度AI总结
        monthly_summary = self.generate_monthly_ai_summary(year, month)
        reports[f"{year}-{month:02d}-summary"] = monthly_summary

        return reports

    def _generate_fallback_daily_report(self, year: int, month: int, day: int, commits: List[CommitInfo]) -> str:
        """生成降级版本的日报（当AI失败时使用）"""
        date_str = f"{year}-{month:02d}-{day:02d}"

        lines = [
            f"## {date_str} 工作日报",
            "",
            "### 提交统计",
            f"- 提交次数: {len(commits)}次",
            f"- 代码变更: +{sum(c.insertions for c in commits)}行 -{sum(c.deletions for c in commits)}行",
            "",
            "### 详细记录"
        ]

        for commit in commits:
            time_str = commit.date.strftime("%H:%M")
            message = commit.message.split('\n')[0]
            lines.append(f"- {time_str} [{commit.repo_name}] {message}")

        return "\n".join(lines)


def load_env_config() -> Dict[str, str]:
    """加载环境变量配置"""
    from dotenv import load_dotenv

    # 尝试加载.env文件（先尝试上级目录，再尝试当前目录）
    env_paths = [
        Path(__file__).parent.parent / '.env',  # 上级目录
        Path(__file__).parent / '.env',  # 当前目录
        Path.cwd() / '.env'  # 工作目录
    ]

    for env_path in env_paths:
        if env_path.exists():
            load_dotenv(env_path)
            logger.info(f"已加载环境变量文件: {env_path}")
            break
    else:
        logger.warning("未找到.env文件，将使用系统环境变量")

    # 获取LLM提供商
    llm_provider = os.getenv('LLM_PROVIDER', 'ollama').lower()

    config = {
        'llm_provider': llm_provider,
        'user_id': os.getenv('DAILY_REPORT_USER_ID'),
        'source_dir': os.getenv('DAILY_REPORT_SOURCE_DIR')
    }

    # 根据提供商添加相应配置
    if llm_provider == 'dashscope':
        config.update({
            'api_key': os.getenv('DASHSCOPE_API_KEY'),
            'model': os.getenv('QWEN_MODEL', 'qwen-plus')
        })
    elif llm_provider == 'ollama':
        config.update({
            'base_url': os.getenv('OLLAMA_BASE_URL', 'http://localhost:11434'),
            'model': os.getenv('OLLAMA_MODEL', 'qwen2.5:32b')
        })

    return config


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='生成AI工作日报')
    parser.add_argument('--year', type=int, default=datetime.now().year, help='年份')
    parser.add_argument('--month', type=int, default=datetime.now().month, help='月份')
    parser.add_argument('--day', type=int, help='日期（如果指定，只生成单日报告）')
    parser.add_argument('--user-id', type=str, help='用户ID')
    parser.add_argument('--source-dir', type=str, help='源代码目录')
    parser.add_argument('--output-dir', type=str, default='./reports', help='输出目录')
    parser.add_argument('--mode', choices=['daily', 'monthly', 'full'], default='full',
                        help='生成模式: daily(单日), monthly(月度总结), full(完整月报)')

    args = parser.parse_args()

    # 加载配置
    config = load_env_config()

    user_id = args.user_id or config['user_id']
    source_dir = args.source_dir or config['source_dir']

    if not user_id:
        logger.error("请指定用户ID")
        sys.exit(1)

    if not source_dir:
        logger.error("请指定源代码目录")
        sys.exit(1)

    # 创建输出目录
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    try:
        # 初始化AI日报生成器
        llm_provider = config['llm_provider']
        llm_config = {k: v for k, v in config.items() if k not in ['llm_provider', 'user_id', 'source_dir']}

        ai_generator = AIDailyReportGenerator(
            llm_provider=llm_provider,
            llm_config=llm_config,
            source_dir=source_dir,
            user_id=user_id
        )

        if args.mode == 'daily' and args.day:
            # 生成单日报告
            report = ai_generator.generate_daily_ai_report(args.year, args.month, args.day)
            output_file = output_dir / f"{args.year}-{args.month:02d}-{args.day:02d}_daily_report.md"

            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(report)

            logger.info(f"单日报告已保存到: {output_file}")
            print(report)

        elif args.mode == 'monthly':
            # 生成月度总结
            summary = ai_generator.generate_monthly_ai_summary(args.year, args.month)
            output_file = output_dir / f"{args.year}-{args.month:02d}_monthly_summary.md"

            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(summary)

            logger.info(f"月度总结已保存到: {output_file}")
            print(summary)

        else:
            # 生成完整月报
            reports = ai_generator.generate_full_monthly_ai_reports(args.year, args.month)

            for report_key, report_content in reports.items():
                output_file = output_dir / f"{report_key}_report.md"

                with open(output_file, 'w', encoding='utf-8') as f:
                    f.write(report_content)

                logger.info(f"报告已保存到: {output_file}")

            logger.info(f"完整月报生成完成，共 {len(reports)} 个文件")

    except Exception as e:
        logger.error(f"生成AI日报时出错: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
